package dbpopulator;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;

/**
 * @author Sadiq Charaniya
 *
 */
public class DBTupleGenerator implements RandomTuples {
	//for table numbers
	private int counter=0;

	private HashMap<String,Comparable[][]> result = new HashMap<String,Comparable[][]>();
	private HashMap<Integer,String> tableIndex = new HashMap<Integer,String>();
	private HashMap<String, String[]> tableAttr = new HashMap<String,String[]>();
	private HashMap<String, String[]> tableDomain = new HashMap<String,String[]>();
	private HashMap<String, String[]> tablepks = new HashMap<String,String[]>();
	HashMap<String, String[][]> tablefks = new HashMap<String,String[][]>();
	public void addRelSchema(String name, String[] attribute, String[] domain,String[] primaryKey, String[][] foreignKey) {
		this.tableIndex.put(counter,name);
		this.tableAttr.put(name,attribute);
		this.tableDomain.put(name, domain);
		this.tablepks.put(name, primaryKey);
		this.tablefks.put(name, foreignKey);
		this.counter++;

	}
/**
 *This method will return the tuples for all the table
 *@param tuples size of each table
 *
 * */

	public Comparable[][][]  generate(int[] tuples) {
		Random rand = new Random();
		String tableName = "";
		String[] attribute;
		String[] domain;
		String[] pks;
		String[][] fks;
		Set pKeys = new HashSet();
		Set pKeyValues = new HashSet();
		Set fKeys = new HashSet();
		ArrayList fkIndex = new ArrayList();


		for(int i =0; i < tuples.length;i++){

			tableName= tableIndex.get(i);

			attribute = tableAttr.get(tableName);
			domain = tableDomain.get(tableName);
			pks = tablepks.get(tableName);
			fks= tablefks.get(tableName);
			Comparable[][] subResult = new Comparable[tuples[i]][attribute.length] ;

			//System.out.println(tableName);
			for(int n=0; n < pks.length;n++){
				pKeys.add(pks[n]);
			}

			if(fks==null){
				for(int j = 0; j < tuples[i]; j++){
					for(int k = 0;k < attribute.length;k++){
						if(pKeys.contains(attribute[k])){
							if(domain[k].equalsIgnoreCase("integer"))
							{
								int intAttr = rand.nextInt(100000);
								while(pKeyValues.contains(intAttr)){
									intAttr = rand.nextInt(100000);
								}
								//System.out.println(i+" "+j+" "+k+" "+intAttr);
								subResult[j][k] = intAttr;
								pKeyValues.add(intAttr);
							}else if(domain[k].equalsIgnoreCase("string")){
								String strAttr = attribute[k]+rand.nextInt(100000);
								while(pKeyValues.contains(strAttr)){
									 strAttr = attribute[k]+rand.nextInt(100000);
								}
								subResult[j][k] = strAttr ;
								pKeyValues.add(strAttr);
							}else if(domain[k].equalsIgnoreCase("double")){
								Double doubleAttr = (rand.nextInt(100000)*rand.nextDouble());
								while(pKeyValues.contains(doubleAttr)){
									doubleAttr = (rand.nextInt(100000)*rand.nextDouble());
								}
								subResult[j][k] = doubleAttr ;
								pKeyValues.add((rand.nextInt(100000)*rand.nextDouble()));
							}
						}
						else{
							if(domain[k].equalsIgnoreCase("integer"))
							{
								int intAttr = rand.nextInt(1000000);
								subResult[j][k] = intAttr ;

							}else if(domain[k].equalsIgnoreCase("string")){
								String strAttr = attribute[k]+rand.nextInt(1000000);
								subResult[j][k] = strAttr ;
								pKeyValues.add(strAttr);
							}if(domain[k].equalsIgnoreCase("double"))
							{
								double doubleAttr = (rand.nextInt(100000)*rand.nextDouble());
								subResult[j][k] = doubleAttr ;

							}
						}

					}
				}

			}else{
				for(int j = 0; j < tuples[i]; j++){
					for(int n=0; n < fks.length;n++){
						if(!fks[n][0].contains(" ")){
							fkIndex.add(n, fks[n][0]);
							Comparable[][] fkTable = result.get(fks[n][1]);
							int s;
							for( s=0; s< attribute.length;s++){
								if(attribute[s].equals(fks[n][0]))
									break;
							}
							String[] tempAtr = tableAttr.get(fks[n][1]);
							int x;
							for(x=0; x< tempAtr.length;x++){
								if(tempAtr[x].equals(fks[n][2]))
									break;
							}
							subResult[j][s] = fkTable[rand.nextInt(fkTable.length)][x];
							//System.out.println("foo"+subResult[j][k]);


						}
						else{
							String[] sfks = fks[n][0].split(" ");
							String[] rfks = fks[n][2].split(" ");
							for(int z=0; z < fks[n][0].split(" ").length;z++){
								fkIndex.add(n+z, fks[n][0].split(" ")[z]);
							}
							Comparable[][] fkTable = result.get(fks[n][1]);
							int t = rand.nextInt(fkTable.length);
							for(int a= 0; a<sfks.length;a++){
								int b;
								for( b=0; b< attribute.length;b++){
									if(attribute[b].equals(sfks[a]))
										break;
								}
								String[] tempAtr = tableAttr.get(fks[n][1]);
								int c;
								for(c=0; c< tempAtr.length;c++){
									if(tempAtr[c].equals(rfks[a]))
										break;
								}
								subResult[j][b] = fkTable[t][c];
							}
						}
					}
					for(int k = 0;k < attribute.length;k++){
						if(!fkIndex.contains(attribute[k])){
							if(pKeys.contains(attribute[k])){
								if(domain[k].equalsIgnoreCase("integer"))
								{
									int intAttr = rand.nextInt(100000);
									while(pKeyValues.contains(intAttr)){
										intAttr = rand.nextInt(100000);
									}
									//System.out.println(i+" "+j+" "+k+" "+intAttr);
									subResult[j][k] = intAttr;
									pKeyValues.add(intAttr);
								}else if(domain[k].equalsIgnoreCase("string")){
									String strAttr = attribute[k]+rand.nextInt(100000);
									while(pKeyValues.contains(strAttr)){
										 strAttr = attribute[k]+rand.nextInt(100000);
									}
									subResult[j][k] = strAttr ;
									pKeyValues.add(strAttr);
								}else if(domain[k].equalsIgnoreCase("double")){
									Double doubleAttr = (rand.nextInt(100000)*rand.nextDouble());
									while(pKeyValues.contains(doubleAttr)){
										doubleAttr = (rand.nextInt(100000)*rand.nextDouble());
									}
									subResult[j][k] = doubleAttr ;
									pKeyValues.add((rand.nextInt(100000)*rand.nextDouble()));
								}
							}else{
								if(domain[k].equalsIgnoreCase("integer"))
								{
									int intAttr = rand.nextInt(1000000);
									subResult[j][k] = intAttr ;

								}else if(domain[k].equalsIgnoreCase("string")){
									String strAttr = attribute[k]+rand.nextInt(1000000);
									subResult[j][k] = strAttr ;

								}else if(domain[k].equalsIgnoreCase("double"))
								{
									double doubleAttr = (rand.nextInt(100000)*rand.nextDouble());
									subResult[j][k] = doubleAttr ;

								}

							}
						}
					}
				}
			}// end if
			pKeys.clear();
			fkIndex.clear();
			result.put(tableName,subResult);
		}

		Comparable[][][] tempResult = new Comparable[result.size()][][];

		for(int i =0; i < result.size();i++){
			tableName= tableIndex.get(i);
			Comparable[][] subTable = result.get(tableName);
			tempResult[i] = subTable;

		}
		return tempResult;
	}


}
